﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Net;
using System.IO;
using System.Reflection;
using Newtonsoft.Json;
using SpeechLib;


namespace 串口程序
{

    public partial class Form1 : Form
    {

        //声明串口
        SerialPort sp = new SerialPort();   

        Messege_Form msg = new Messege_Form(); 

        public delegate void Displaydelegate(byte[] InputBuf);
        
        public Displaydelegate disp_delegate;

        Updater updater = new Updater("XultimateX", "assist");

        public Data data;

        Byte[] OutputBuf = new Byte[128];

        public Form1()
        {
            disp_delegate = new Displaydelegate(DispUI);
            sp.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
            InitializeComponent();

            if (updater.check())
            {
                MessageBox.Show(updater.LatestReleaseBody + "\n" + updater.LatestReleaseName, "新版更新提示：");
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            init_comobox();

        }

        //下拉菜单初始化
        private void init_comobox()
        {
            string[] names = SerialPort.GetPortNames();
            string[] BaudRate = new string[] { "4800", "9600", "14400", "19200", "38400", "56000", "57600", "115200" };
            string[] CheckBit = new string[] { "2" };
            string[] DataBit = new string[] { "5", "6", "7", "8" };
            string[] StopBit = new string[] { "1", "1.5", "2" };

            comboBox_assist.Items.AddRange(names);
            comboBox_baudrate.Items.AddRange(BaudRate);
            comboBox_checkbit.Items.AddRange(CheckBit);
            comboBox_databit.Items.AddRange(DataBit);
            comboBox_stopbit.Items.AddRange(StopBit);

            comboBox_assist.SelectedIndex = 0;
            comboBox_baudrate.SelectedIndex = 1;
            comboBox_checkbit.SelectedIndex = 0;
            comboBox_databit.SelectedIndex = 3;
            comboBox_stopbit.SelectedIndex = 0;
        }

        //打开串口按钮单击事件
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (button1.Text == "打开串口")
                {
                    if (comboBox_assist.SelectedIndex == -1)
                    {
                        msg.createForm("先选择串口号再打开串口...");
                        return;
                    }
                    sp.PortName = comboBox_assist.SelectedItem.ToString();
                    sp.BaudRate = 9600;
                    sp.Parity = Parity.None; //new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
                    sp.DataBits = 8;
                    sp.StopBits = StopBits.One;
                    sp.Open();
                    button1.Text = "关闭串口";
                    button1.ForeColor = Color.Red;
                }
                else
                {
                    sp.Close();
                    button1.Text = "打开串口";
                    button1.ForeColor = Color.Black;
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            Byte[] InputBuf = new Byte[128];

            try
            {
                sp.Read(InputBuf, 0, sp.BytesToRead);                                //读取缓冲区的数据直到“}”即0x7D为结束符  
                //InputBuf = UnicodeEncoding.Default.GetBytes(strRD);             //将得到的数据转换成byte的格式  
                System.Threading.Thread.Sleep(50);               
                this.Invoke(disp_delegate, InputBuf);
                //ASCIIEncoding encoding = new ASCIIEncoding();
                //string text = encoding.GetString(InputBuf);
                //sp.Write(text);
                //System.Threading.Thread.Sleep(50);
                //data = new Data(text);
                //Console.WriteLine("头数据-" + data.DataHead
                //                    + "\nData8数据-" + data.Data8.Print()
                //                    + "\n校验数据" + data.DataCheck
                //                    + "\n结束位" + data.DataEnd
                //                    + "\n");

            }
            catch (TimeoutException ex)         //超时处理  
            {
                MessageBox.Show(ex.ToString() + " 超时");
            }
        }

        public void DispUI(byte[] InputBuf)
        {
            //textBox1.Text = Convert.ToString(InputBuf);  

            //ASCIIEncoding encoding = new ASCIIEncoding();
            //richTextBox1.Text = encoding.GetString(InputBuf);

            data = new Data(
                            new ASCIIEncoding().GetString(InputBuf),
                            int.Parse(comboBox_checkbit.Text),
                            int.Parse(comboBox_databit.Text),
                            int.Parse(comboBox_stopbit.Text)
                            );

            //richTextBox1.Text += "\n头数据-" + data.DataHead
            //                        + "\nData8数据-" + data.Data8.Print()
            //                        + "\n校验数据" + data.DataCheck
            //                        + "\n结束位" + data.DataEnd
            //                        + "\n";
            richTextBox1.ScrollToCaret();
            richTextBox1.AppendText(
                                        "头数据-" + data.DataHead
                                        + "\nData8数据-" + data.Data8.Print()
                                        + "\n校验数据" + data.DataCheck
                                        + "\n结束位" + data.DataEnd
                                        + "\r\n"
                                   );
            string path = Environment.CurrentDirectory + @"\"+"Resource"+@"\"+"2926.wav";
            new System.Media.SoundPlayer(path).Play();
            
            SpVoice voice = new SpVoice();
            voice.Voice = voice.GetVoices(string.Empty, string.Empty).Item(0);
            voice.Rate = -3;
            voice.Volume = 100;
            System.Threading.Thread.Sleep(800);
            voice.Speak(data.Data8.Number + "号机呼叫", SpeechVoiceSpeakFlags.SVSFlagsAsync);

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (!sp.IsOpen)
            {
                msg.createForm("打开串口后重试发送...");
                return;
            }
            ASCIIEncoding encoding = new ASCIIEncoding();
            sp.Write(richTextBox2.Text);
        }
    }

    public class Data
    {
        public int DataBit { get; private set; }

        public int CheckBit { get; private  set; }

        public int StopBit { get; private set; }

        public string DataHead { get; private set; }

        public data8 Data8;

        public string DataCheck { get; private set; }

        public string DataEnd { get; private set; }

        private string[] record;

        //public struct data8
        //{
        //    public int Year;
        //    public int Month;
        //    public int Number;
        //    public int Hour;
        //    public int Minute;
        //    public int KeyValue;
        //    public int Second;
        //    public int Day;

        //    public int Sum()
        //    {
        //        return Year + Month + Number + Hour + Minute + KeyValue + Second + Day;
        //    }

        //    public string Display()
        //    {
        //        return Year.ToString() + Month.ToString() + Number.ToString() + Hour.ToString() + Minute.ToString() + KeyValue.ToString() + Second.ToString() + Day.ToString();
        //    }
        //}

        public struct data8
        {
            public string Year;
            public string Month;
            public string Number;
            public string Hour;
            public string Minute;
            public string KeyValue;
            public string Second;
            public string Day;

            //public int Sum()
            //{
            //    return Year + Month + Number + Hour + Minute + KeyValue + Second + Day;
            //}

            public override string ToString()
            {
                return Year + " " + Month + " " + Day + " " + Hour + " " + Minute + " " + Second + " " + Number + " " + KeyValue;
            }

            public string Print()
            {
                return Year + "年" + Month + "月" + Day + "日" + Hour + "时" + Minute + "分" + Second + "秒\n" + Number + "分机编号" + KeyValue + "键值";
            }
        }

        public Data(string data, int checkbit, int databit, int stopbit)
        {
#if DEBUG
            Console.WriteLine("\n Data构造函数");
            //string[] b = data.Split(' ');
            //foreach (var str in b)
            //{
            //    Console.WriteLine(str + " b数组");
            //}           
#endif  
            record = data.Split(' ');  
            
            CheckBit = checkbit;
            DataBit = databit;
            StopBit = stopbit;

            SetData();
        }

        public void SetData()
        {
            SetDataHead();
            SetData8();
            SetCheck();
            SetEnd();
#if DEBUG
            Console.WriteLine("DataHead "+DataHead + "|Data8 " + Data8.ToString() + "|DataCheck " + DataCheck +"|DataEnd "+ DataEnd + "\n");
#endif
        }

        private void SetDataHead()
        {
            string value = "";
            for (int i = 0; i < DataBit; i++)
            {
                value += record[i] + " ";
            }
            DataHead = value;
        }

        //private void SetData8()
        //{
        //    Data8.Year = int.Parse(record[7]);
        //    Data8.Month = int.Parse(record[8]);
        //    Data8.Number = int.Parse(record[9] + record[10]);
        //    Data8.Hour = int.Parse(record[11]);
        //    Data8.Minute = int.Parse(record[12]);
        //    Data8.KeyValue = int.Parse(record[13]);
        //    Data8.Second = int.Parse(record[14]);
        //    Data8.Day = int.Parse(record[15]);
        //}

        private void SetData8()
        {
            //Data8.Year = record[7];
            //Data8.Month = record[8];
            //Data8.Number = record[9] + record[10];
            //Data8.Hour = record[11];
            //Data8.Minute = record[12];
            //Data8.KeyValue = record[13];
            //Data8.Second = record[14];
            //Data8.Day = record[15];

            Data8.Year = record[DataBit - 1];
            Data8.Month = record[DataBit];
            Data8.Number = record[DataBit + 1] + record[DataBit + 2];
            Data8.Hour = record[DataBit + 3];
            Data8.Minute = record[DataBit + 4];
            Data8.KeyValue = record[DataBit + 5];
            Data8.Second = record[DataBit + 6];
            Data8.Day = record[DataBit + 7];
        }

        private void SetCheck()
        {
            DataCheck = record[16];
        }

        private void SetEnd()
        {
            DataEnd = record[17];
        }
    }

    public class Messege_Form/*提示框 类*/ : Form
    {
        public int returnvalue = -1;/*确定返回1，取消返回0，关闭返回-1*/
        public const int 是否钮 = 1, 确定钮 = 0;
        public enum ButtonKind
        {
            YN = 1,
            Sure = 0
        }

        /*------------------------------------------------------------------*/

        public Messege_Form()
        {
            this.TopMost = true;
            this.Size = new Size(250, 165);
            //this.Icon = Resource1.logo1;
            this.MaximizeBox = this.MinimizeBox = false;
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            this.StartPosition = FormStartPosition.CenterParent;
            this.FormClosing += new FormClosingEventHandler(Closing_MessegeForm);

        }

        public void createForm(string msg)
        {
            System.Media.SystemSounds.Beep.Play();

            Create_Button(ButtonKind.Sure);
            Create_Lable(msg);

            this.Text = "提示：";
            this.ShowDialog();
        }

        public void createForm(string msg, string caption, ButtonKind kind = ButtonKind.Sure)
        {
            System.Media.SystemSounds.Beep.Play();

            Create_Button(ButtonKind.Sure);
            Create_Lable(msg);

            this.Text = caption;
            this.ShowDialog();
        }


        private void Create_Lable(string msg)
        {
            Label label = new Label();
            label.Font = new Font(label.Font.FontFamily, 9, label.Font.Style);
            label.TextAlign = ContentAlignment.MiddleCenter;
            label.Size = new Size(this.Width, 16);
            label.Location = new Point(-10, 32);
            label.Text = msg;
            label.Visible = true;
            this.Controls.Add(label);
        }

        private void Create_Button(ButtonKind kind)
        {
            Button sure = new Button();
            sure.Location = new Point(70, 78);
            sure.Size = new Size(90, 30);
            sure.TextAlign = ContentAlignment.MiddleCenter;
            sure.Font = new Font(sure.Font.FontFamily, 9);
            sure.Text = "确定";
            sure.Click += new EventHandler(Click_Sure);

            Button cancel = new Button();
            cancel.Location = new Point(120, 78);
            cancel.Size = new Size(90, 30);
            cancel.TextAlign = ContentAlignment.MiddleCenter;
            cancel.Font = new Font(sure.Font.FontFamily, 9);
            cancel.Text = "取消";
            cancel.Click += new EventHandler(Click_Cancel);

            if (kind == ButtonKind.Sure)
            {
                cancel.Visible = false;
            }
            else if (kind == ButtonKind.YN)
            {
                sure.Left = 25;
            }

            this.Controls.Add(sure);
            this.Controls.Add(cancel);
        }

        private void Click_Sure(object sender, EventArgs e)
        {
            returnvalue = 1;
            this.Close();
        }

        private void Click_Cancel(object sender, EventArgs e)
        {
            returnvalue = 0;
            this.Close();
        }

        private void Closing_MessegeForm(object sender, EventArgs e)
        {
            Console.WriteLine("ReturnValue: " + returnvalue);
            this.Controls.Clear();
            return;
        }
    }

    public class Updater
    {
        //当前版本号
        private Version CurrentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

        //最新版本号
        public Version LatestVersion { get; private set; }

        //最新发布名称
        public string LatestReleaseName { get; private set; }

        //最新发布介绍
        public string LatestReleaseBody { get; private set; }

        //最新发布地址
        public string Url { get; set; }

        //更新可用
        public bool UpdaterEnable = false;

        public Updater(string url)
        {
            Url = url;
        }

        public Updater(string owner, string path)
        {
            Url = "https://git.oschina.net/api/v5/repos/" + owner + "/" + path + "/releases/latest";
        }
        //更新回执信息
        public struct JSON
        {
            public string id { get; set; }
            public string tag_name { get; set; }
            public string target_commitish { get; set; }
            public string name { get; set; }
            public string body { get; set; }
        }

        private string value;

        //检查更新
        public bool check()
        {

            try
            {

                WebClient MyWebClient = new WebClient();

                MyWebClient.Credentials = CredentialCache.DefaultCredentials;//获取或设置用于向Internet资源的请求进行身份验证的网络凭据

                Byte[] pageData = MyWebClient.DownloadData(Url); //从指定网站下载数据

                //string pageHtml = Encoding.Default.GetString(pageData);  //如果获取网站页面采用的是GB2312，则使用这句            

                string pageHtml = Encoding.UTF8.GetString(pageData); //如果获取网站页面采用的是UTF-8，则使用这句

                //Console.WriteLine(pageHtml);//在控制台输入获取的内容

                value = pageHtml;

            }

            catch (WebException webEx)
            {

                Console.WriteLine(webEx.Message.ToString());
                return UpdaterEnable;
            }
            
            var release = JsonConvert.DeserializeObject<JSON>(value);

            LatestVersion = new Version(release.tag_name.Trim('v'));
            LatestReleaseName = release.name;
            LatestReleaseBody = release.body.Replace(@"\r\n", "\n");

            //比较最新版本和当前版本
            if (LatestVersion > CurrentVersion)
            {
#if DEBUG
                Console.WriteLine(Assembly.GetExecutingAssembly().GetName().Name + "有新版可以更新");
#endif

                //更新可用为真
                UpdaterEnable = true;
            }
            else
            {
#if DEBUG
                Console.WriteLine(Assembly.GetExecutingAssembly().GetName().Name + "无需更新");
#endif
            }
            return UpdaterEnable;
        }

        public void SetUrl(string str)
        {
            Url = str;
        }

        public void SetUrl(string owner, string path)
        {
            Url = "https://git.oschina.net/api/v5/repos/" + owner + "/" + path + "/releases/latest";
        }


    }

}
